// 用户访问行为模块
class userAccess {
  // 初始化
  constructor(ctx) {
    ctx = ctx || {};
    if (!ctx || typeof ctx._cloud != 'object') {
      throw new Error('初始化用户访问模块时，请传入小程序实例化后的cloud对象');
    }

    const _mfutil = ctx._that;
    this._mfutil = ctx._that;
    this._cloud = ctx._cloud || ''; // 小程序cloud对象必传
    this._device = _mfutil.mobileInfo;    //  用户当前使用的设备信息
    this._avatar = '';    //  用户头像
    this._usernick = '';    //  用户昵称
    this._emitter = ctx._emitter || '';  // 发送消息对象
    this._needMember = ctx.needMember || false;  //是否需要查询会员信息
    this._refresh_authorization_info = false;  // 是否进行二次触发更新用户昵称和头像
    this._network = {};   //  网络状态
    // 去缓存里面拿信息
    this._userInfo = {};
    this._oncoming_user_member = {};
    this._emitter = ctx._emitter || '';
  }

  // 授权
  async onAuthorizate(options) {
    // 设置用户头像和昵称
    const { avatar = '', nickName = '' } = options;
    this._avatar = avatar;
    this._usernick = nickName;
    // 如果 用户信息为空需要等待 refreshAuthorization 的操作
    if (Object.keys(this._userInfo).length == 0) {
      this._emitter.on("refreshAuthorization", () => {
        this.refreshUserInfo(avatar, nickName);
      });
    } else {
      this.refreshUserInfo(avatar, nickName);
    }
  }

  // 判断并修改用户昵称和头像
  async refreshUserInfo(avatar, nickName) {
    if (this._userInfo.avatar != avatar || this._userInfo.nickName != nickName) {
      await this.insertKey({ avatar, nickName })
      await this.getSql();
    }
  }

  // 用户首次进入小程序，初始化用户信息
  async onAppInit(options) {
    // 创建用户记录，增加基数功能
    await this.insert({});
    // 将创建记录的接口也改为可以返回用户信息的接口
    await this.getSql();
    this._needMember && await this.getIdentityMessage();
    // 打印用户信息
    console.log('用户信息:', this._userInfo);
    // 触发用户授权第一次没有无法触发的事件
    this._refresh_authorization_info && this._emitter.emit('refreshAuthorization');
  }

  // 获取用户信息 status 为 true  数据库查询数据并返回，false 本地获取并返回
  async get(status = false) {
    //  是否从数据库获取
    if (status) {
      return await this.getSql();
    } else {
      // 如果缓存里面没有的话就去数据库里面拿
      if (Object.keys(this._userInfo).length != 0) {
        return this._userInfo;
      } else {
        return await this.getSql();
      }
    }
  }

  // 从缓存中获取用户信息 提供给埋点模块使用
  async getCacheUserInfo() {
    if (Object.keys(this._userInfo).length != 0) {
      return this._userInfo;
    } else {
      return null;
    }
  }

  // 获取本次用户会员信息
  async getOncomingUserMemberInfo() {
    if (Object.keys(this._oncoming_user_member).length != 0) {
      return this._oncoming_user_member;
    } else {
      return null;
    }
  }

  // 从数据获取用户信息
  async getSql() {
    try {
      const res = await this.request({ name: 'userAccessCloud', handler: 'get' });
      if (res.success && res.data && res.data[0]) {
        this._userInfo = res.data[0];
      } else {
        this._userInfo = {};
      }
      return this._userInfo;
    } catch (e) {
      console.log('%c userAccess 模块的从数据获取用户信息存在异常!' + JSON.stringify(e), 'color: red');
    }
  }

  // 调用后端接口 查询用户会员信息 ,返回用户会员等级
  async getIdentityMessage() {
    // 会员状态
    let member = '-1';
    try {
      const res = await this.request({
        name: 'userAccessCloud',
        handler: 'member'
      });
      if (res.success && res.data && res.data.res && res.data.res.result) {
        // 会员详情
        const memberInfo = res.data.res.result;
        // 会员状态

        if (memberInfo.member_info) {
          const grade = memberInfo.member_info.grade;
          member = grade ? grade + '' : '0'
        }
        // 给全局赋值
        this._oncoming_user_member = {
          memberInfo,
          member
        };
        // 进行广播事件
        this._emitter && this._emitter.emit('changeMemberState', member);

        // 判断是否初始化完成 判断会员状态是否发生变化,更新用户信息
        if (Object.keys(this._userInfo).length != 0 && this._userInfo.member != member) {
          await this.insertKey({ member, memberInfo })
          await this.getSql();
        }
      } else {
        console.log('%c userAccess 模块的查询用户会员信息存在异常(请确认权限是否存在)!', 'color: red');
        console.log('%c userAccess 接口返回值:' + JSON.stringify(res), 'color: red');
      }

    } catch (e) {
      console.log('%c userAccess 模块的查询用户会员信息存在异常!' + JSON.stringify(e), 'color: red');
    } finally {
      return member;
    }
  }

  //  增加用户信息字段
  async insertKey(obj) {
    try {
      // 判断新的 key 是否存在
      obj = obj || {};
      if (Object.keys(obj).length === 0) {
        console.log('%c userAccess 模块 请传入所要新增的字段对象！' + JSON.stringify(obj), 'color: red');
        return;
      }

      // 调用云函数
      await this.request({ name: 'userAccessCloud', params: obj, handler: 'insertKey' });
      // 更新缓存的数据
      await this.getSql();
    } catch (e) {
      console.log('%c userAccess 模块的增加用户信息字段存在异常!' + JSON.stringify(e), 'color: red');
    }
  }

  // 新增用户信息
  async insert(obj) {
    try {
      // 参数拼装
      const obj = {
        avatar: this._avatar || '',
        appName: this._device.app || '淘宝',
        appVersion: this._device.version || '0.0.0',
        phonePlatform: this._device.platform || '未知',
        phoneModel: this._device.model || '未知',
        phoneSystem: this._device.system || '未知',
        network: this._network,
        device: this._device,
        ...obj
      };

      const res = await this.request({ name: 'userAccessCloud', params: obj, handler: 'insert' });
      //  console.log(res);
      //  if (res.success && res.data && res.data[0]) {
      //   this._userInfo = res.data[0];
      // } else {
      //   this._userInfo = {};
      // }
      // return this._userInfo;
    } catch (e) {
      console.log('%c userAccess 模块的新增用户信息存在异常!' + JSON.stringify(e), 'color: red');
    }
  }

  // 发送请求 默认为云函数
  async request(obj, type = 'cloud') {
    // 判断 userAccess 模块的云函数请求是否存在异常
    if (typeof this._cloud != 'object') {
      console.log('%c userAccess 模块的云函数请求存在异常!', 'color: red');
      return;
    } else {
      if (type === 'cloud') {
        return await this._cloud.function.invoke(obj.name, obj.params, obj.handler);
      } else {
        return await this._cloud.application.httpRequest({
          'path': obj.path,
          'method': obj.method,
          'headers': obj.headers,
          'params': obj.params,
          'body': obj.body,
          'exts': obj.exts
        });
      }
    }
  }
}

module.exports = exports.userAccess = userAccess;